mongoose = require('mongoose')
winston = require('winston')
require('winston-flume').flumeLogger
config = require("../config")
util = require("util")
utils = require("../lib/utils")
default_gfsrc = utils.default_gfsrc
#kafka = require('./kafka')

#console.log('logging __dirname = %s', __dirname)


info_logger = new (winston.Logger)({
  transports: [
    new (winston.transports.DailyRotateFile)(
        level:"info"
        filename: config.services.log.path + '/info.log'
        json: false
        maxsize:10*1024*1024
        timestamp: -> new Date(new Date().getTime() + 8*3600000).toISOString()
    )
  ]
  exitOnError: false
})


# 事务日志
trans_logger = new (winston.Logger)({
  transports: [
    new (winston.transports.DailyRotateFile)(
        level:"info"
        filename: config.services.log.path + '/trans.log'
        json: false
        maxsize:10*1024*1024
        timestamp: -> new Date(new Date().getTime() + 8*3600000).toISOString()
    )
  ]
  exitOnError: false
})


exports.logger = logger = new (winston.Logger)({
  transports: [
    new (winston.transports.File)(
        level:"info"
        filename: __dirname + '/logs/info/info.log'
        json: false
        maxsize:10*1024*1024
        timestamp: -> new Date(new Date().getTime() + 8*3600000).toISOString()
    )
    new (winston.transports.Console)(
        level:"error"
        json: false
        timestamp: -> new Date(new Date().getTime() + 8*3600000).toISOString()
    )
  ],
  exceptionHandlers: [
    new (winston.transports.File)(
        filename: __dirname + '/logs/exception.log'
        json: false
        maxsize:10*1024*1024
        timestamp: -> new Date(new Date().getTime() + 8*3600000).toISOString()
    )
  ],
  exitOnError: false
})


if config.services.flume.ip and config.services.flume.port
  flume_logger = new (winston.Logger)({
    transports: [
      new (winston.transports.flumeLogger)({ 'host': config.services.flume.ip, 'port': config.services.flume.port })
    ],
    exitOnError: false
  })
else
  flume_logger = null

exports.flume_logger = flume_logger

exports.error_logger =  new (winston.Logger)({
  transports: [
    new (winston.transports.File)(
        level:"error"
        filename: __dirname + '/logs/error.log'
        json: false
        maxsize:10*1024*1024
        timestamp: -> new Date(new Date().getTime() + 8*3600000).toISOString()
    )
    new (winston.transports.Console)(
        level:"error"
        json: false
        timestamp: -> new Date(new Date().getTime() + 8*3600000).toISOString()
    )
  ],
  exceptionHandlers: [
    new (winston.transports.File)(
        filename: __dirname + '/logs/exception.log'
        json: false
        maxsize:10*1024*1024
        timestamp: -> new Date(new Date().getTime() + 8*3600000).toISOString()
    )
  ],
  exitOnError: false
})

exports.log = (app,obj) ->
  
  if obj == undefined or obj == null
    obj = {}
    
  if typeof(obj) == "object"
    unless obj.date
      obj.date = new Date().toFormat("YYYY-MM-DD")
    unless obj.time
      obj.time = new Date().toFormat("YYYY-MM-DD HH24:MI:SS")
    obj.app = app

    unless obj.src
      obj.src = g_default_gfsrc
    

  unless typeof(obj) == "string"
    obj = JSON.stringify obj
    
  if flume_logger
    flume_logger.log("info",obj,{})
    info_logger.info obj    
  else
    console.log "info:#{obj}"

 
exports.log_trans_begin = (trans_id, data) ->
  log_trans({id:trans_id, type:"begin", data})

exports.log_trans_end   = (trans_id) ->
  log_trans({id:trans_id, type:"end"})


exports.log_trans_info   = (trans_id, data) ->
  log_trans({id:trans_id, type:"info",data})

    

exports.log_trans = log_trans = (obj) ->
  
  if obj == undefined or obj == null
    obj = {}

  if typeof(obj) == "object"
    
    unless obj.date
      obj.date = new Date().toFormat("YYYY-MM-DD")
    unless obj.time
      obj.time = new Date().toFormat("YYYY-MM-DD HH24:MI:SS")
  
  unless typeof(obj) == "string"
    obj = JSON.stringify obj

  trans_logger.info obj



g_default_gfsrc = default_gfsrc()  
g_request_handling_total = 0

exports.logging_middleware = (req,res,next) ->
    res.original_send = res.send
    req.logging_info =
      ip: req.ip
      originalUrl: req.originalUrl
      referer: req.header("X-Referer") or req.header('Referer') or  "" # X-Referer 是前端设置
      userAgent: req.header('User-Agent') ? ""
      t0: new Date().getTime()
      fullurl : req.protocol + '://' + req.get('host') + req.originalUrl
    g_request_handling_total++
    res.send =  ->
      console.log "process:#{process.pid} request handling total:#{g_request_handling_total}"
      g_request_handling_total--
      trackCookie = req.cookies?.GF_GFW_TRACK ? ""
      if not trackCookie
        trackCookie = (new mongoose.Types.ObjectId()).toString()
        res.cookie('GF_GFW_TRACK', trackCookie,{expires:new Date(Date.parse('2033-01-01T00:00:00.000Z')) })
      res.original_send.apply(this, arguments)
      sessionId = ""
      username= ""
      tradeId = ""
      src = g_default_gfsrc
      session = req.session or req.__gf_session
      sessionId = session?.id
      src = session?.gfsrc  || g_default_gfsrc
      info = req.logging_info
      time_cost = (new Date().getTime()) - info.t0

      console.log(util.format('access: `%s`%s`%s`%s`%s`%s`%s`%s`%d`%d`%s`%s',
          info.ip, info.originalUrl, info.referer, info.userAgent,
          trackCookie, sessionId, username, tradeId, res.statusCode, 
          time_cost, JSON.stringify(src), req.method))
      # if flume_logger
      if true
        obj =
          date: new Date().toFormat("YYYY-MM-DD")
          time: new Date().toFormat("YYYY-MM-DD HH24:MI:SS")
          type: "access"
          ip: info.ip
          originalurl: info.originalUrl
          referer: info.referer
          useragent: info.userAgent
          trackcookie: trackCookie
          sessionid: sessionId
          statuscode: res.statusCode
          timing: (new Date().getTime()) - info.t0
          src: src
          fullurl : info.fullurl
          app_id : "gfw"
        obj_str = JSON.stringify(obj)
        #kafka.send obj_str
        info_logger.info obj_str
    next()

